package processor

import (
	"context"
	"gitee.com/go-mid/auth/authservice"
	"gitee.com/go-mid/booter"
	"gitee.com/go-mid/booter/bootservice"
	"gitee.com/go-mid/booter/web"
	"gitee.com/go-mid/infra/xcore"
	"gitee.com/go-mid/infra/xlog"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"net/http"
)

func Auth() bootservice.HandlerFunc {
	return func(c *bootservice.Context) {
		ctx := c.Request.Context()
		path := c.Request.URL.Path
		if IsSkipAuth(ctx, path) {
			c.Next()
			return
		}
		_, err := web.Authenticate(ctx, c.Request, func(ctx2 context.Context, tk string) (web.XFRMAuthInfo, error) {
			authRes, err := authservice.DefaultAuthService.Auth(ctx, &authservice.AuthReq{
				AccessToken: tk,
			})
			if err != nil {
				xlog.Infof(ctx, "auth fail: tk: %s, err: %v", tk, err)
				return web.XFRMAuthInfo{}, err
			}
			return authRes.AuthInfo, nil
		})
		if err != nil {
			//将错误码，强制改成 鉴权未通过
			sts, ok := status.FromError(err)
			if !ok {
				sts = status.New(codes.Unauthenticated, err.Error())
			} else {
				sts = status.New(codes.Unauthenticated, sts.Message())
			}
			c.AbortWithStatusJSON(http.StatusUnauthorized, web.ApiReturn{
				Status: sts.Proto(),
			})
			return
		}
		c.Next()
	}
}

//todo  改造到数据库中维护，使用正则表达式处理，
//目前先写死
func IsSkipAuth(ctx context.Context, path string) bool {
	urisStr, _ := booter.GlobalServer.ConfigCenter(ctx).GetString(ctx, "application", "skip_uris")
	var skipPathMap = make(map[string]interface{})
	for _, uri := range xcore.SplitAndTrim(ctx, urisStr, ",", true) {
		skipPathMap[uri] = struct{}{}
	}
	if _, ok := skipPathMap[path]; ok {
		return true
	}
	return false
}
